﻿using System.Collections.Generic;
using System.Linq;

namespace YawetagLib.Linq
{
    public struct AccessorDef
    {
        private const string SELF_ACCESSOR = "{self}";
        private const string SELF_PROPERTY_NAME = "_SELF_";

        internal static AccessorDef New(string propertyName, string accessor)
        {
            string[] accessorParts = accessor.Split('.');

            return new AccessorDef
            {
                AccessorParts = accessorParts, PropertyName = GetCheckedPropertyName(propertyName, accessor, accessorParts)
            };
        }

        internal static AccessorDef New(string accessor)
        {
            return New(string.Empty, accessor);
        }

        internal static AccessorDef New()
        {
            return New(SELF_ACCESSOR);
        }

        private static string GetCheckedPropertyName(string propertyName, string accessor, IList<string> accessorParts)
        {
            return string.IsNullOrEmpty(propertyName) 
                ? (accessor.Equals(SELF_ACCESSOR) ? SELF_PROPERTY_NAME : accessorParts[accessorParts.Count - 1]) 
                : propertyName;
        }

        public string PropertyName { get; private set; }

        private string[] AccessorParts { get; set; }

        public string Accessor
        {
            get { return AccessorParts.Aggregate((a, i) => a + "." + i); }
        }

        public string FirstPart
        {
            get { return AccessorParts[0]; }
        }

        public bool IsNested
        {
            get { return AccessorParts.Length > 1; }
        }

        public bool IsSelfReferenced
        {
            get { return Accessor.Equals(SELF_ACCESSOR); }
        }

        public AccessorDef NextDefinition
        {
            get { return IsNested ? New(AccessorParts.Skip(1).Aggregate((a, i) => a + "." + i)) : default(AccessorDef); }
        }
    }
}
